package im.yisme.view.ui;

import im.yisme.R;
import im.yisme.view.activities.GameActivity;
import im.yisme.view.activities.RecordActivity;
import im.yisme.view.service.GameViewService;
import im.yisme.view.ui.RecordView.PaintThread;
import im.yisme.view.ui.animation.Bloom;
import im.yisme.view.ui.animation.Clock;
import im.yisme.view.ui.animation.Combo;
import im.yisme.view.ui.animation.Comet;
import im.yisme.view.ui.animation.Door;
import im.yisme.view.ui.animation.Halo;
import im.yisme.view.ui.animation.Level;
import im.yisme.view.ui.animation.Score;
import im.yisme.view.ui.animation.Tail;
import im.yisme.view.ui.animation.pojo.ClockPOJO;
import im.yisme.view.ui.animation.pojo.ComboPOJO;
import im.yisme.view.ui.animation.pojo.DoorPOJO;
import im.yisme.view.ui.animation.pojo.HaloPOJO;
import im.yisme.view.ui.animation.pojo.LevelPOJO;
import im.yisme.view.ui.animation.pojo.LineBitmapPOJO;
import im.yisme.view.ui.animation.pojo.LinePOJO;
import im.yisme.view.ui.animation.pojo.ScorePOJO;
import im.yisme.view.ui.component.ComponentInvolved;
import im.yisme.view.ui.component.YButton;
import im.yisme.view.ui.util.UIparams;
import im.yisme.view.ui.util.YViewThread;

import java.util.ArrayList;
import java.util.Iterator;

import android.R.integer;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameView extends YView implements GameViewService,ComponentInvolved{

	private SurfaceHolder holder;
	private GameActivity activity;
	
	//-------------------------------------------------
		// 手势轨迹消除线程
		private Tail tailThread;
		// 点击反馈线程队列
		private ArrayList<Halo> haloThreadArrayList;
		// 点击提示动画线程队列
		private ArrayList<Clock> clockThreadArrayList;
		// 手势提示动画线程队列
		private ArrayList<Bloom> bloomThreadArrayList;
		private ArrayList<Comet> cometThreadArrayList;
		// 分数更新线程
		private Score scoreThread;
		// Combo更新线程
		private Combo comboThread;
		// 击打Level线程
		private Level levelThread;
		// 加载效果线程
		private Door doorThread;
	//-------------------------------------------------
		
	//-------------------------------------------------
	//常量
		
		public static final int PAUSE_POLLING_INTERVAL= 500;
		private static final int MAX_LENGTH_OF_TRACK=10;	
	//--------------------------------------------------
		
		
    //--------------------------------------------------
	// 加载界面
		private DoorPOJO door;
		private boolean loadCompletion;
		
	//--------------------------------------------------
		
	// --------------------------------------------------------
	// 4个圆点
		
		private int r = 80;
		private RectF[] pillar = new RectF[UIparams.NUM_OF_PILLAR];
		private Bitmap pillarBitmap;
	// --------------------------------------------------------

		
	// --------------------------------------------------------
	// 点击反馈动画队列
		private ArrayList<HaloPOJO> haloArrayList;
	// 手势轨迹动画队列
		private ArrayList<LinePOJO> trackArrayList;
		private boolean isBeginTrack;//轨迹开始标志
	// 点击提示动画队列
		private ArrayList<ClockPOJO> clockArrayList;
	// 手势提示动画队列
		private ArrayList<HaloPOJO> bloomArrayList;
		private ArrayList<LineBitmapPOJO> cometArrayList;
	//  得分
		private Bitmap scoreBGP;
		private ScorePOJO score;
		private ComboPOJO combo;
		
    //  level
		private LevelPOJO level;
		private Bitmap perfect,good,bad;
    //  背景
		private Bitmap bgp,bgp1,bgp2,bgp3;
		private int index;
		private int count;
	    private static final int NUM_OF_BGP=3;
	//---------------------------------------------------------
		
	// --------------------------------------------------------
	// 组件
		private ArrayList<YButton> buttonList;
	//---------------------------------------------------------
		
		
	public GameView(Context context,GameActivity activity) {
		super(context);
		this.activity = activity;
		//初始化
		init();
		
	}

	

	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		
	}

	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		start();
	}

	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		stop();
	}

	//-----------------------------------------------------------
	// 对GameActivity提供的接口
    public void start(){
		
		paintThread=new PaintThread(holder);
		paintThread.start();
		
		tailThread=new Tail(trackArrayList);
		tailThread.start();
	}
	public void pause(){
		
		tailThread.pauseRunning();
		
		Iterator<Halo> itHalo=haloThreadArrayList.iterator();
		while (itHalo.hasNext()) {
			Halo halo = itHalo.next();
			halo.pauseRunning();
		}		
		Iterator<Clock> itClock=clockThreadArrayList.iterator();
		while (itClock.hasNext()) {
			Clock clock = itClock.next();
			if(clock!=null) clock.pauseRunning();
		}
		Iterator<Bloom> itBloom=bloomThreadArrayList.iterator();
		while (itBloom.hasNext()) {
			Bloom bloom = itBloom.next();
			if(bloom!=null) bloom.pauseRunning();
		}
		Iterator<Comet> itComet=cometThreadArrayList.iterator();
		while (itComet.hasNext()) {
			Comet comet = itComet.next();
			if(comet!=null) comet.pauseRunning();
		}
	}
	public void resume(long putOffTime){
		tailThread.resumeRunning();
		
		Iterator<Halo> it=haloThreadArrayList.iterator();
		while (it.hasNext()) {
			Halo halo = it.next();
			if(halo!=null) halo.resumeRunning();
		}
		Iterator<Clock> itClock=clockThreadArrayList.iterator();
		while (itClock.hasNext()) {
			Clock clock = itClock.next();
			if(clock!=null) clock.resumeRunning(putOffTime);
		}
		Iterator<Bloom> itBloom=bloomThreadArrayList.iterator();
		while (itBloom.hasNext()) {
			Bloom bloom = itBloom.next();
			if(bloom!=null) bloom.resumeRunning(putOffTime);
		}
		Iterator<Comet> itComet=cometThreadArrayList.iterator();
		while (itComet.hasNext()) {
			Comet comet = itComet.next();
			if(comet!=null) comet.resumeRunning(putOffTime);
		}
	}
	public void stop(){
		super.stop();
		tailThread.stopRunning();
	}
	public void addNewMovePoint(PointF point){
		PointF lastPoint;
		if(isBeginTrack || trackArrayList.size() == 0){
			lastPoint=point;
			isBeginTrack=false;
		}
		else 
			lastPoint=trackArrayList.get(0).getHead();
		
		LinePOJO tempLinePOJO=new LinePOJO(point, lastPoint);
		trackArrayList.add(0, tempLinePOJO);
		
		if(trackArrayList.size()>MAX_LENGTH_OF_TRACK) trackArrayList.remove(MAX_LENGTH_OF_TRACK);
	}
	public void setTrackBegin(){
		isBeginTrack=true;
	}
	public void clock(int whichPillar,long bestTime){
		Clock clock=new Clock(bestTime, 
				              new PointF(UIparams.center[whichPillar][0], 
				            		     UIparams.center[whichPillar][1]),
				              r, 
				              clockArrayList, 
				              clockThreadArrayList,
				              getResources());
		clock.start();
	}
	public void bloom(int whichPillar,long bestTime,boolean isActive,boolean isLink){
		Bloom bloom=new Bloom(bestTime, 
							  new PointF(UIparams.center[whichPillar][0], 
									     UIparams.center[whichPillar][1] ), 
							  bloomArrayList, 
							  bloomThreadArrayList,
							  getResources());
		if(isActive) bloom.living();
		else bloom.dead();

		if(isLink) bloom.isLink();
		
		bloom.start();
	}
	public void comet(int points[],long bestTime,boolean isActive){
		
		for(int i=0;i<points.length;i++){
			points[i] = (points[i]+1) * (points[i]+1);
		}
		Comet comet=new Comet(bestTime, 
				              points, 
				              cometArrayList, 
				              cometThreadArrayList,
				              getResources());
		
		if(isActive) comet.living();
		else comet.dead();
		
		comet.start();
	}
	public void dieCurrentLine(){
		if(cometThreadArrayList.size() != 0){
			cometThreadArrayList.get(0).dead();
		}
	}
	public void updateScore(int score){
		scoreThread.setRealScore(score);
	}
	public void updateCombo(int combo){
		comboThread.setRealCombo(combo);
	}
	public void finishLoading(){
		loadCompletion = true;
		activity.start();
	}

	//----------------------------------------------------
	
	
	
	//-----------------------------------------------
	// 对外提供接口
	public void validTap(int whichPillar) {
		// TODO Auto-generated method stub
		Halo halo=new Halo(new PointF(UIparams.center[whichPillar][0],
				                      UIparams.center[whichPillar][1]),
				           r,
				           haloArrayList,haloThreadArrayList,
				           getResources());
		halo.start();
	}
	public void addYButton(YButton button) {
		// TODO Auto-generated method stub
		buttonList.add(button);
	}
	public void levelResult(String level){
		
		this.level = new LevelPOJO();
		
		if(level.equals("Perfect!")){
			this.level.setLevel(perfect);
		}
		else if(level.equals("Good!")){
			this.level.setLevel(good);
		}
		else if(level.equals("Bad>_<")){
			this.level.setLevel(bad);
		}
		
		
		levelThread = new Level(this.level);
		levelThread.start();
		
	}
	//-----------------------------------------------
	
	// ----------------------------------------------------------------
	// 绘图线程
		class PaintThread extends YViewThread {


			public PaintThread(SurfaceHolder holder) {
				super(holder);
			}
			@Override
			protected void paint(Canvas canvas) {
				// TODO Auto-generated method stub
				canvas.setDrawFilter(new PaintFlagsDrawFilter(0,
						Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG));
				

				Paint p = new Paint();
				p.setAntiAlias(true);  
				canvas.drawColor(Color.WHITE);
				
				
				
			
				if(loadCompletion){
					
					if(!activity.pause)	count++;
					if(count == 3){
						index = (index+1)%(NUM_OF_BGP+1);
						count = 0;
						bgp = getBGP(index);
					}
					
					
					if(bgp != null)
					canvas.drawBitmap(bgp, 0, 0, p);
					
					
					//----------------------------------
					// 画手势提示轨迹Comet
					
					int size1 = cometArrayList.size();
					for(int i=0;i<size1;i++){
						
						LineBitmapPOJO linePOJO;
						try {
							linePOJO = cometArrayList.get(i);
						} catch (Exception e) {
							// TODO: handle exception
							continue;
						}

						ArrayList<Bitmap> lines = linePOJO.getLines();
						ArrayList<PointF> points = linePOJO.getPoints();
						
						p.setAlpha(linePOJO.getAlpha());
						
						int length = lines.size();
						for(int j=0;j<length;j++){
							canvas.drawBitmap(lines.get(j), points.get(j).x, points.get(j).y, p);
						}	
					}
					//----------------------------------
					

					// ---------------------------------
					// 画六个柱子
					p.setAlpha(255);

					for (RectF r : pillar) {
						canvas.drawBitmap(pillarBitmap, r.left, r.top, p);
					}
					// ---------------------------------

					// ---------------------------------
					// 画得分
					   p.setTextSize(27);
					   canvas.drawBitmap(scoreBGP, 0, 0, p);
					   canvas.drawText(score.getScore()+"", 30, 30, p);
					   
					// 画Combo和击打状态
					   
					   p.setAlpha(combo.getAlpha());
					  
					   ArrayList<Bitmap> comboBitmap = combo.getComboList();
					   ArrayList<PointF> comboPoint = combo.getComboPointList();
					   
					   int size0 = comboBitmap.size();
					   for(int i=0;i<size0;i++)
					   canvas.drawBitmap(comboBitmap.get(i), comboPoint.get(i).x, comboPoint.get(i).y,p);
					   
					   
					   
					   p.setAlpha(level.getAlpha());
					   Bitmap levelBitmap = level.getLevel();
					   PointF pointF = level.getPoint();
					   
					   if(levelBitmap != null)
					   canvas.drawBitmap(levelBitmap, pointF.x, pointF.y, p);
					// ---------------------------------
					   
					   
					//----------------------------------
					// 画点击反馈
					
					
					int size2 = haloArrayList.size();
					for(int i=0;i<size2;i++){
						HaloPOJO halo;
						try {
							halo = haloArrayList.get(i);
						} catch (Exception e) {
							// TODO: handle exception
							continue;
						}
						
						p.setAlpha(halo.getAlpha());
						Bitmap haloBitmap = halo.getHalo();
						PointF point = halo.getHaloPointF();
						
						canvas.drawBitmap(haloBitmap, point.x, point.y, p);
					}
					//----------------------------------
					
					//----------------------------------
					// 画手势轨迹
					p.setColor(Color.YELLOW);
					
					int lineAlpha=255;
					int size = trackArrayList.size();
					for(int i=0;i<size;i++){
						LinePOJO line;
						try {
							line = trackArrayList.get(i);
						} catch (Exception e) {
							// TODO: handle exception
							continue;
						}
						
						p.setAlpha(lineAlpha);
						
						canvas.drawLine(line.getHead().x, line.getHead().y, 
								        line.getTail().x, line.getTail().y, 
								        p);
						
						lineAlpha=lineAlpha-(255/MAX_LENGTH_OF_TRACK);
					}
					//----------------------------------
					
					
					
					//----------------------------------
					// 画手势提示Bloom
					p.setAlpha(255);
					p.setFilterBitmap(true);
					int size3 = bloomArrayList.size();
					for(int i=0;i<size3;i++){

						HaloPOJO haloPOJO;
						try {
							haloPOJO = bloomArrayList.get(i);
						} catch (Exception e) {
							// TODO: handle exception
							continue;
						}
						 p.setAlpha(haloPOJO.getAlpha());
		                    Bitmap haloBitmap = haloPOJO.getHalo();
		                    PointF point = haloPOJO.getHaloPointF();
		                  
		                    p.setAlpha(haloPOJO.getAlpha());
		                    if(haloBitmap != null)
		                    canvas.drawBitmap(haloBitmap, point.x, point.y, p);
		                    
					}
					//----------------------------------
				
					
					
					
					//----------------------------------
					// 画点击提示
					
					int size4 = clockArrayList.size();
					for(int i=0;i<size4;i++){
						ClockPOJO clockPOJO;
						try {
							clockPOJO = clockArrayList.get(i);
						} catch (Exception e) {
							// TODO: handle exception
							e.printStackTrace();
							continue;
						}
						Bitmap sector = clockPOJO.getSector();
						Bitmap substrate = clockPOJO.getSubstrate();
						PointF sectorPoint = clockPOJO.getSectorPoint();
						
						p.setAlpha(clockPOJO.getSectorAlpha());
						if(substrate != null)
						canvas.drawBitmap(substrate, sectorPoint.x, sectorPoint.y, p);
						
						canvas.drawBitmap(sector, sectorPoint.x, sectorPoint.y, p);
						
					}
					//----------------------------------
					
					
					
					//----------------------------------
					//暂停幕布
					if(activity.pause){
						p.setColor(Color.BLACK);
						p.setAlpha(140);
						canvas.drawRect(new RectF(0, 0, UIparams.screenWidth, UIparams.screenHeight), p);
					}
					//----------------------------------
					
					
					//----------------------------------
					// 画组件
					p.setAlpha(255);
					
					Iterator<YButton> itButton=buttonList.iterator();
					while (itButton.hasNext()) {
						YButton yButton = itButton.next();
						if(!yButton.isVisible()) continue;
						
						if(yButton.getBGP() != null) canvas.drawBitmap(yButton.getBGP(), yButton.getX(), yButton.getY(), p);
					}
					//----------------------------------
					
					
				}
							
				
				// ---------------------------------
				// 加载界面
				
				if(door.getRightPoint() != null){
					 PointF left = door.getLeftPoint();
					 PointF right = door.getRightPoint();
					 Bitmap door_left = door.getDoor_left();
					 Bitmap door_right = door.getDoor_right();
					 
					 p.setTextSize(30);
					 
					 canvas.drawBitmap(door_right, right.x, right.y, p);
					 canvas.drawBitmap(door_left, left.x, left.y, p);
					 
					 Rect rect = new Rect();
					 String text = door.getLoadingText();
					 p.getTextBounds(text, 0, text.length(), rect);
					 
					 canvas.drawText(text, 395-rect.width()/2, 255 - rect.height()/2, p);
			
				}
				else {
					doorThread.stopRunning();
				}
				
				// ---------------------------------
				
			}

		}
	
	//私有方法
	
	private void initPillar() {
		for (int i = 0; i < UIparams.NUM_OF_PILLAR; i++) {
			pillar[i] = new RectF(UIparams.center[i][0] - r, UIparams.center[i][1] - r,
					UIparams.center[i][0] + r, UIparams.center[i][1] + r);
		}

		pillarBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.game_pillar);
	}
	
	private void init() {
		// TODO Auto-generated method stub
		
		holder = this.getHolder();
		holder.addCallback(this);
        trackArrayList=new ArrayList<LinePOJO>();
        haloArrayList=new ArrayList<HaloPOJO>();
        clockArrayList=new ArrayList<ClockPOJO>();
        bloomArrayList=new ArrayList<HaloPOJO>();
        cometArrayList=new ArrayList<LineBitmapPOJO>();
        
        
        haloThreadArrayList=new ArrayList<Halo>();
        clockThreadArrayList=new ArrayList<Clock>();
        bloomThreadArrayList=new ArrayList<Bloom>();
        cometThreadArrayList=new ArrayList<Comet>();
       
        
        buttonList=new ArrayList<YButton>();
        
        isBeginTrack=true;
        initPillar();
        initBitmap();
        
        
        score = new ScorePOJO();
        scoreThread = new Score(score);
        scoreThread.start();
        
        combo = new ComboPOJO();
        comboThread = new Combo(combo,getResources());
        comboThread.start();
        
        level = new LevelPOJO();
        levelThread = new Level(level);
        
        door = new DoorPOJO();
        doorThread = new Door(door, getResources(), this);
        doorThread.start();
        
        count = 0;
	}


	private void initBitmap(){
		scoreBGP = BitmapFactory.decodeResource(getResources(), R.drawable.game_score);
		bgp1 = BitmapFactory.decodeResource(getResources(), R.drawable.game_bgp1);
		bgp2 = BitmapFactory.decodeResource(getResources(), R.drawable.game_bgp2);
		bgp3 = BitmapFactory.decodeResource(getResources(), R.drawable.game_bgp3);
		bgp = bgp1;
		
		perfect = BitmapFactory.decodeResource(getResources(), R.drawable.perfect);
		good = BitmapFactory.decodeResource(getResources(), R.drawable.good);
		bad = BitmapFactory.decodeResource(getResources(), R.drawable.bad);
	}

	private Bitmap getBGP(int index){
		Bitmap bm = null;
		switch (index) {
		case 0:
			bm = bgp1;
			break;
		case 1:
			bm = bgp2;
			break;
		case 2:
			bm = bgp3;
			break;
		case 3:
			bm = bgp2;
			break;
		default:
			break;
		}
		
		return bm;
	}
	@Override
	protected void createThread() {
		// TODO Auto-generated method stub
		paintThread = new PaintThread(holder);
	}



	



	
	
}
